using System;
using System.Collections.Generic;

namespace Kopernikus.Parsing.Utility
{
    public class Permuter<T>
    {
        private readonly int m_count;
        private readonly T[] m_items;

        public Permuter(IEnumerable<T> items)
        {
            m_items = new List<T>(items).ToArray();

            m_count = NFak(m_items.Length);
        }

        public int Count
        {
            get { return m_count; }
        }

        private static int NFak(int n)
        {
            int f = 1;
            for (int i = 2; i <= n; ++i)
            {
                f *= i;
            }
            return f;
        }

        public T[] CreatePermutation(int k)
        {
            T[] p = new T[m_items.Length];
            Array.Copy(m_items, p, m_items.Length);
            int f = 1;
            for (int j = 2; j <= p.Length; ++j)
            {
                f *= (j - 1);

                int a = j - 1;
                int b = (j - ((k/f)%j)) - 1;
                T tmp = p[a];
                p[a] = p[b];
                p[b] = tmp;
            }
            return p;
        }
    }
}